package com.wswy.wzcx.ui.main.community

import android.arch.lifecycle.LiveData
import android.arch.lifecycle.MutableLiveData
import com.che.libcommon.utils.RxBus
import com.che.libcommon.utils.optional.Optional
import com.wswy.wzcx.api.Api
import com.wswy.wzcx.model.Converter
import com.wswy.wzcx.model.topic.TopicModel
import com.wswy.wzcx.module.InternalMsgCode
import com.wswy.wzcx.module.base.Resource
import com.wswy.wzcx.module.base.UserViewModel
import com.wswy.wzcx.module.base.onResult
import com.wswy.wzcx.utils.RxUtils
import io.reactivex.observers.ResourceObserver

class CommunityViewModel : UserViewModel(){

    companion object {
        const val TYPE_ADD = 1
        const val TYPE_DELETE = 2

        const val TYPE_LIKE = 3

        const val TYPE_ADD_COMMENT = 4
    }

    private val topicUpdateLiveData = MutableLiveData<String?>()
    private val topicListLiveData = MutableLiveData<Resource<List<TopicVO>>>()
    private val topicLoadMoreLiveData = MutableLiveData<Resource<List<TopicVO>>>()



    private val topicChangeLiveData = MutableLiveData<Pair<Int,TopicModel>?>()

    private var nextId :Long = 0

    private var firstId : Long = 0

    override fun onCreate() {
        super.onCreate()
        registerObservers()
    }

    override fun registerObservers() {
        super.registerObservers()

        val topicAdd = object : ResourceObserver<TopicModel>() {
            override fun onNext(topicMode: TopicModel) {
                topicChangeLiveData.postValue(Pair(TYPE_ADD,topicMode))
            }

            override fun onError(e: Throwable) {
            }

            override fun onComplete() {
            }
        }

        val topicDelete = object : ResourceObserver<TopicModel>() {
            override fun onNext(topicMode: TopicModel) {

                topicChangeLiveData.postValue(Pair(TYPE_DELETE,topicMode))
            }

            override fun onError(e: Throwable) {

            }

            override fun onComplete() {

            }
        }


        val topicLike = object : ResourceObserver<TopicModel>() {
            override fun onNext(topicMode: TopicModel) {
                topicChangeLiveData.postValue(Pair(TYPE_LIKE,topicMode))
            }

            override fun onError(e: Throwable) {
            }

            override fun onComplete() {
            }
        }

        val topicAddComment = object : ResourceObserver<TopicModel>() {
            override fun onNext(topicMode: TopicModel) {
                topicChangeLiveData.postValue(Pair(TYPE_ADD_COMMENT,topicMode))
            }

            override fun onError(e: Throwable) {
            }

            override fun onComplete() {
            }
        }

        //添加
        RxBus.getDefault().toObservableWithCode(InternalMsgCode.CODE_TOPIC_ADD, TopicModel::class.java)
                .subscribe(topicAdd)

        RxBus.getDefault().toObservableWithCode(InternalMsgCode.CODE_TOPIC_DELETE,TopicModel::class.java)
                .subscribe(topicDelete)

        RxBus.getDefault().toObservableWithCode(InternalMsgCode.CODE_TOPIC_LIKE,TopicModel::class.java)
                .subscribe(topicLike)

        RxBus.getDefault().toObservableWithCode(InternalMsgCode.CODE_TOPIC_COMMIT,TopicModel::class.java)
                .subscribe(topicAddComment)

        addRun(topicAdd)
        addRun(topicDelete)
        addRun(topicLike)
        addRun(topicAddComment)
    }

    fun loadData(isFirst :Boolean =  false){
        topicUpdateLiveData.postValue(null)
        topicLoadMoreLiveData.postValue(Resource.success(null))

        addRun(Api.get().topicList(0,firstId).compose(RxUtils.switch2io()).map {
            val ret = arrayListOf<TopicVO>()

            it.orNull()?.list?.run {

                forEach {
                    it?.run {
                        ret.add(Converter.convert2TopicVO(this,true))
                    }
                }

                if (isNotEmpty()){
                    firstId = first()?.id?:0
                    nextId = last()?.id?:0
                }
            }?:kotlin.run {
                firstId = 0
                nextId = 0
            }

            topicUpdateLiveData.postValue(it.orNull()?.updateNumber)

            Optional.ofNullable(ret.toList())
        }.onResult({
            topicListLiveData.postValue(Resource.success(it))
        },{
            topicListLiveData.postValue(Resource.error(it,isFirst))
        }))
    }

    fun canLoadMore():Boolean = nextId != -1L

    fun loadMore(){


        addRun(Api.get().topicList(nextId,0).compose(RxUtils.switch2io()).map {
            val ret = arrayListOf<TopicVO>()

            it.orNull()?.list?.run {

                forEach {
                    it?.run {
                        ret.add(Converter.convert2TopicVO(this,true))
                    }
                }

                nextId = if (isNotEmpty()){
                    val id = last()?.id?:0
                    if (id >0 && id != nextId){
                        id
                    }else{
                        -1
                    }
                }else{
                    -1
                }

            }?:kotlin.run {
                nextId = -1
            }
            Optional.ofNullable(ret.toList())
        }.onResult(topicLoadMoreLiveData))
    }

    fun changeConsumed(){
        topicChangeLiveData.postValue(null)
    }

    fun getTopicListLiveData():LiveData<Resource<List<TopicVO>>> = topicListLiveData

    fun getTopicLoadMoreLiveData():LiveData<Resource<List<TopicVO>>> = topicLoadMoreLiveData

    fun getUpdateNumLiveData():LiveData<String?> = topicUpdateLiveData

    fun getTopicChangeLiveData():LiveData<Pair<Int,TopicModel>?> = topicChangeLiveData
}